/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-04
 * V4.0
 */
package com.jphenix.kernel.objectloader.instanceb;

import com.jphenix.driver.log.FLog;
import com.jphenix.driver.log.systemouta.SystemOutLog;
import com.jphenix.driver.nodehandler.FNodeHandler;
import com.jphenix.driver.propertie.FConfProp;
import com.jphenix.driver.propertie.instanceb.XmlConfProp;
import com.jphenix.kernel.classloader.ResourcesLoader;
import com.jphenix.kernel.objectloader.exception.BeanException;
import com.jphenix.kernel.objectloader.interfaceclass.IBean;
import com.jphenix.kernel.objectloader.interfaceclass.IBeanFactory;
import com.jphenix.kernel.objectloader.vo.BeanVO;
import com.jphenix.share.lang.*;
import com.jphenix.share.util.ClassUtil;
import com.jphenix.share.util.DebugUtil;
import com.jphenix.share.util.SFilesUtil;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.lang.ILangType;
import com.jphenix.standard.log.ILog;
import com.jphenix.standard.log.ILogShadow;
import com.jphenix.standard.viewhandler.INodeHandler;
import com.jphenix.standard.viewhandler.IViewHandler;
import com.jphenix.ver.PhenixVer;

import java.io.File;
import java.lang.reflect.Array;
import java.util.*;

/**
 * XML配置文件解析类
 * 
 * 2018-09-05 去掉了BeanFactory中的confProp类实例，只使用当前类中的
 * 2018-09-13 简化了整个架构中日志初始化步骤
 * 2018-11-08 去掉了配置信息类中设置的是否为开发模式参数（从来没用过）
 * 2019-01-24 修改了ClassLoader，简化了程序结构
 * 2020-08-06 修改了配置文件处理接口，改为直接使用实体类
 * 2021-03-16 整理了代码缩进
 * 2021-09-12 修改了加载配置文件部分的代码
 * 
 * @author 刘虻
 * 2010-2-3 下午01:36:32
 */
@ClassInfo({"2021-09-12 18:50","XML配置文件解析类"})
public class XmlConfigParse {

  protected BeanFactory beanFactory = null;  // 类加载器
  protected int         idIndex     = 0;     // 自动主键索引
  protected ILogShadow  logShadow   = null;  // 日志影子类
  protected ILog        log         = null;  // 日志文件对象
  protected XmlConfProp confProp    = null;  // 配置文件管理类
  //private boolean loadInsideBean  = false; // 是否已经加载了内部类 已经停用，实在没这个必要

  /**
   * 构造函数
   * @author 刘虻
   */
  public XmlConfigParse(BeanFactory beanFactory) {
    super();
    this.beanFactory = beanFactory;
  }

  /**
   * 初始化驱动级模块
   * 刘虻
   * 2010-5-13 下午12:53:20
   * @param xml            配置文件对象
   * @param configPath     当前配置文件所在文件夹路径
   * @param configFilePath 当前文件路径
   * @throws Exception 执行发生异常
   */
  protected void initDriver(IViewHandler xml,String configPath,String configFilePath) throws Exception {
	  if(xml==null) {
		  return;
	  }
	  //加载内部配置信息
	  confProp = FConfProp.newInstance(beanFactory);
	  //内部配置文件
	  List<IViewHandler> nPxmlList = xml.getChildNodesByNodeName("native_property");
	  for(IViewHandler ele:nPxmlList) {
		  confProp.addFilePath(ele.nt().trim());
	  }
	  String propFilePath = ""; //配置文件路径
	  //参数配置信息
	  IViewHandler confXml = xml.getFirstChildNodeByNodeName(IBeanFactory.TAG_PROPERTIES_FILE_PATH);
	  if(confXml!=null) {
		  //参数配置文件路径
		  propFilePath = confXml.nt().trim();
	  }
	  if(propFilePath.length()<1) {
		  propFilePath = "properties.xml";
	  }
	  
	  // 解析配置信息段
	  confProp.parsePropertys(xml.getFirstChildNodeByNodeName("properties"),null);
	  
	  if(SFilesUtil.isFileExist(propFilePath,beanFactory.getWebInfPath())) {
		  propFilePath = SFilesUtil.getAllFilePath(propFilePath,beanFactory.getWebInfPath());
		  confProp.addFilePath(propFilePath);
	  }else if(propFilePath.startsWith("!")) {
		  //内部资源
		  confProp.addFilePath(propFilePath);
	  }
	  /*
	   * 先加载正式的配置文件
	   * 再检查是否允许并存在开发环境配置文件，
	   * 如果存在，则重新加载开发环境配置信息，并进入开发模式
	   */
	  beanFactory.developMode = false; //是否为开发模式
	  String devPropFilePath = ""; //开发环境配置文件路径
	  if(!SBoolean.valueOf(confProp.getParameter("disabled_develop_parameter_file"))) {
		  //现从正式配置文件中获取开发配置文件相对路径（相对于WEB-INF文件夹）
		  devPropFilePath = confProp.getParameter("develop_parameter_file_path");
		  if(devPropFilePath.length()<1) {
			  //开发模式参数配置信息
			  IViewHandler devConfXml = xml.getFirstChildNodeByNodeName(IBeanFactory.TAG_DEVELOP_PROPERTIES_FILE_PATH);
			  if(devConfXml!=null) {
				  //参数配置文件路径
				  devPropFilePath = devConfXml.nt().trim();
			  }
		  }
		  if(devPropFilePath.length()>0) {
			  if(SFilesUtil.isFileExist(devPropFilePath,beanFactory.getWebInfPath())) {
				  devPropFilePath = SFilesUtil.getAllFilePath(devPropFilePath,beanFactory.getWebInfPath());
				  //重新加载
				  confProp = FConfProp.newInstance(beanFactory);
				  for(IViewHandler ele:nPxmlList) {
					  confProp.addFilePath(ele.nt().trim());
				  }
				  //加载开发模式的参数配置文件
				  confProp.addFilePath(devPropFilePath);
				  beanFactory.developMode = true;
			  }
		  }
	  }
	  //加载项目基础信息
	  beanFactory.projectName = confProp.getParameter("project_name");
	  beanFactory.projectCode = confProp.getParameter("project_code");
	  beanFactory.projectPin  = confProp.getParameter("project_pin").toUpperCase();
	  if(!beanFactory.developMode) {
		  beanFactory.developMode = SBoolean.valueOf(confProp.getParameter("development_mode"));
	  }
	  //日志文件路径
	  String logConfigPath = null;
	  //日志配置信息
	  IViewHandler logXml = xml.getFirstChildNodeByNodeName(IBeanFactory.TAG_LOG_CONFIG_FILE_PATH);
	  if(logXml!=null && !logXml.isEmpty() ) {
		  //日志配置文件路径
		  logConfigPath = logXml.nt().trim();
	  }else {
		  // 根配置文件中包含了日志类声明
		  logConfigPath = configFilePath;
	  }
		  /* 不要写死，可以没有日志配置文件路径
	    else {
	      //没有设置日志配置文件路径
	      //先从从默认路径 /WEB-INF/resfiles中查找是否有 log.xml
	      logConfigPath = "/resfiles/log.xml";
	      if((new File(beanFactory.getWebInfPath()+logConfigPath)).exists()) {
	        //读取本地日志配置文件
	        configPath = beanFactory.getWebInfPath();
	      }else {
	        //从压缩包中获取配置文件
	        //处理掉内部资源标识符
	        logConfigPath = "!"+logConfigPath;
	      }
	    }
		   */
	  if(logConfigPath.startsWith("!")) {
		  //配置文件保存在了框架内部资源中
		  //处理掉内部资源标识符
		  logConfigPath = logConfigPath.substring(1);
		  //内部资源加载器
		  ResourcesLoader rl = beanFactory.getObject(ResourcesLoader.class,this);
		  try {
			  logShadow = FLog.getLogShadow(rl.getFile(logConfigPath),logConfigPath,beanFactory,beanFactory.developMode,confProp);
		  }catch(Exception e) {
			  e.printStackTrace();
			  throw new BeanException("Load Log Config File:["+logConfigPath+"] Exception:"+DebugUtil.outException(e));
		  }
	  }else {
		  logShadow = 
				  FLog.getLogShadow(
						  SFilesUtil.getAllFilePath(logConfigPath,SFilesUtil.getFilePath(configPath))
						  ,beanFactory,beanFactory.developMode,confProp);
	  }
	  if(logShadow==null) {
		  log = new SystemOutLog();

	  }else {
		  beanFactory.setObject(logShadow.getClass(),logShadow);
		  log = FLog.getLog(logShadow,this);
	  }
	  //在初始化日志后，输出框架版本信息
	  log.startLog(PhenixVer.getVerInfo());
	  log.startLog("Load Properties File:["+propFilePath+"]");
	  if(beanFactory.developMode) {
		  log.startLog("Load Develop Properties File:["+devPropFilePath+"]");
		  log.startLog("<<DevelopMode Enabled>>");
	  }
  }

  /**
   * 初始化配置文件中的常量
   * 
   * 通常类配置文件中放的常量都是不经常改变值的
   * 
   * 配置文件中的常量信息优先顺序为最后，如果.conf(参数配置文件)文件中也存在
   * 该常量，则优先取.conf中的
   * 
   * 刘虻
   * 2010-6-3 上午09:34:09
   * @param xml        配置文件对象
   * @throws Exception 执行发生异常
   */
  protected void initConfigParameter(IViewHandler xml) throws Exception {
    if(xml==null) {
      return;
    }
    //获取常量信息对象数组
    List<IViewHandler> xmls = xml.getChildNodesByNodeName(IBeanFactory.TAG_PROPERTIES);
    if(xmls.size()<1) {
      return;
    }
    //获取子节点序列
    xmls = xmls.get(0).getChildDealNodes();
    String key = null; //常量主键
    String value = null; //常量值
    //获取重定向类根路径
    for(IViewHandler cXml:xmls) {
      key = cXml.nn();
      value = cXml.nt();
      if(key==null || key.length()<1) {
        continue;
      }
      //获取参数配置文件容器
      HashMap<String,Object> confPropMap = confProp.getParameterMap();
      if(confPropMap.containsKey(key)) {
        //以参数配置文件中的值优先，省略类配置文件中声明的常量
        continue;
      }
      if(value==null) {
        value = "";
      }
      /*
        没有必要这么做，因为放入到ConfProp的类中，这个类本身就支持@处理
        if(value.startsWith("!")) {
          类配置文件中的常量实际上是一个变量，取自参数配置文件中
          value = confProp.getFixParameter(value);
        }
      */
      confPropMap.put(key,value);
    }
  }

  /**
   * 加载指定配置文件中的类
   * 刘虻
   * 2010-2-3 下午04:38:36
   * @param configFilePath 配置文件路径
   * @param beanVOMap      将类信息放入该容器中
   * @param loadBeanPKList 将类主键放入该序列中
   * @param beanVO         需要重新初始化的
   * @throws Exception     执行发生异常
   */
  protected void parseBeanVO(
      String             configFilePath,
      Map<String,BeanVO> beanVOMap,
      ArrayList<String>  loadBeanPKList,
      BeanVO             beanVO) throws Exception {
    if(configFilePath==null || configFilePath.length()<1) {
      throw new BeanException("Bean Config File Path Is Null");
    }
    //构建XML实例
    INodeHandler configXml = FNodeHandler.newNodeHandler();
    configXml.setXmlStyle(true);
    String cfgFilePath = configFilePath;
    if(cfgFilePath.startsWith("!")) {
      //内部资源
      //处理掉内部资源标识符
    	cfgFilePath = cfgFilePath.substring(1);
      //内部资源加载器
      ResourcesLoader rl = beanFactory.getObject(ResourcesLoader.class,this);
      try {
        //Xml配置文件
        configXml.setStream(rl.getFile(cfgFilePath),cfgFilePath); //设置xml文件
      }catch(Exception e) {
        e.printStackTrace();
        throw new BeanException("Load Config File:["+cfgFilePath+"] Exception:"+DebugUtil.outException(e));
      }
    }else {
      try {
        //Xml配置文件
        configXml.setStream(SFilesUtil.getFileInputStreamByUrl(cfgFilePath,null),cfgFilePath); //设置xml文件
      }catch(Exception e) {
        e.printStackTrace();
        throw new BeanException("Load Config File:["+cfgFilePath+"] Exception:"+DebugUtil.outException(e));
      }
    }
    if(SBoolean.valueOf(configXml.getFirstChildNodeByNodeName(IBeanFactory.TAG_BEAN_DISABLED).nt())) {
      log.log("The Config File Has Disabled ["+cfgFilePath+"]");
      return;
    }
    //将主配置文件路径作为配置文件相对的根路径
    String configFileBasePath = SFilesUtil.getFilePath(cfgFilePath,false);
    if(SBoolean.valueOf(configXml.getFirstChildNodeByNodeName("root_config").nt())) {
      initDriver(configXml,configFileBasePath,configFilePath); //初始化驱动类
    }
    //初始化jar包内部的受BeanFactory管理的类
    //必须在初始化驱动类后，才能干这个
    //loadInsideBean(); //已经停用，实在没这个必要
    log.startLog("Load Config File:["+cfgFilePath+"]");
    initConfigParameter(configXml); //初始化类配置文件常量信息段
    /*
     * 先加载当前配置文件中的类
     */
    try {
      // 设置当前配置文件中的bean信息
      setBeanFromConfig(configXml,beanVOMap,loadBeanPKList,beanVO);
    }catch(Exception e) {
      e.printStackTrace();
      throw new BeanException(
        "Parse Config File:["+configFileBasePath
        +"] Exception:"+DebugUtil.outException(e));
    }
    // 获取引用子配置文件路径段数组
    List<IViewHandler> importXmls = configXml.getChildNodesByNodeName(IBeanFactory.TAG_IMPORT);
    List<IViewHandler> filePathXmls; //获取配置文件路径
    String allPath; //全路径 
    for (IViewHandler importXml:importXmls) {
      // 获取配置文件路径
      filePathXmls = importXml.getChildNodesByNodeName(IBeanFactory.TAG_IMPORT_FILE_PATH);
      String importilePath; //获取子配置文件路径
      for (IViewHandler filePathXml:filePathXmls) {
        importilePath = filePathXml.nt();
        if (importilePath==null || importilePath.trim().length()<1) {
          continue;
        }
        //构造为全路径
        importilePath = importilePath.trim();
        allPath = SFilesUtil.getAllFilePath(importilePath,configFileBasePath);
        log.startLog("Load Import Config File:["+importilePath+"]");
        File path = new File(allPath); //路径对象
        if(path.isDirectory()) {
          //加载指定文件夹中的配置文件
          //搜索到的文件序列
          ArrayList<String> filePathList = new ArrayList<String>();
          //执行搜索
          SFilesUtil.getFileList(filePathList,allPath,null,"xml",true,false);
          //构建排序对象
          SortVector<String> sv = new SortVector<String>();
          int point; //文件排序分割节点
          String fileName; //文件名
          for(String filePathEle:filePathList) {
            fileName = SFilesUtil.getFileName(filePathEle);
            if(fileName.toLowerCase().endsWith("_disabled.xml")) {
              continue;
            }
            point = fileName.indexOf("_");
            if(point>-1) {
              sv.add(filePathEle,SDouble.valueOf(fileName.substring(0,point)));
            }else {
              sv.add(filePathEle,99);
            }
          }
          sv.asc(); //由小到大排序
          while(sv.hasNext()) {
            // 加载引用配置文件
            parseBeanVO(
              sv.nextValue(),
              beanVOMap,
              loadBeanPKList,
              beanVO);
          }
        }else if(path.isFile()) {
          // 加载引用配置文件
          parseBeanVO(allPath,beanVOMap,loadBeanPKList,beanVO);
        }else if(importilePath.startsWith("!")) {
          //内置资源
          parseBeanVO(importilePath,beanVOMap,loadBeanPKList,beanVO);
        }else {
          log.warning("Not Find The Include File Path Into Config File ["+importilePath+"] AllPath:["+allPath+"]",null);
        }
      }
    }
  }

  /**
   * 构造一个新的唯一的类主键
   * 刘虻
   * 2012-12-11 下午2:32:27
   * @return 类主键
   */
  protected String getNewBeanID() {
    if(idIndex==99999) {
      idIndex = 0;
    }
    return "no_id_"+System.currentTimeMillis()+"_"+(idIndex++);
  }

  /**
   * 从配置文件中获取信息设置BeanVO
   * 刘虻
   * 2010-2-3 下午05:27:27
   * @param xml            配置文件对象
   * @param beanVOMap      将类信息放入该容器中
   * @param loadBeanPKList 将类主键放入该序列中
   * @param beanVO         待初始化的信息容器，如果为空，则为新增
   * @throws Exception     执行发生异常
   */
  protected void setBeanFromConfig(
    IViewHandler       xml,
    Map<String,BeanVO> beanVOMap,
    List<String>       loadBeanPKList,
    BeanVO             beanVO) throws Exception {
    //导入参数合法化
    if (xml==null) {
      return;
    }
    boolean isReset = beanVO != null; //是否为重新初始化
    // 获取bean声明段数组
    List<IViewHandler> beanXmls = xml.getChildNodesByNodeName(IBeanFactory.TAG_BEAN);
    for (IViewHandler beanXml:beanXmls) {
      //获取类主键
      String beanID = beanXml.a(IBeanFactory.TAG_BEAN_ID);
      // 无主键bean  比如动作类，不需要其它类调用
      if (beanID.length()<1) {
        beanID = getNewBeanID();
      }
      if(isReset && !beanVO.id.equals(beanID)) {
        //如果是重新初始化指定信息类
        continue;
      }
      BeanVO thisBeanVO = null; //当前类信息容器
      try {
        thisBeanVO = setOneBeanFormConfig(beanXml,beanVOMap,beanVO);
        if (thisBeanVO==null) {
          continue;
        }
      } catch (Exception e) {
        e.printStackTrace();
        if(!isReset) {
          thisBeanVO = new BeanVO();
          thisBeanVO.id = beanID;
        }
        thisBeanVO.state = IBeanFactory.STATE_EXCEPTION_INFO;
        thisBeanVO.errorMsg = e.toString();
      }
      //标记加载信息完毕  
      //不用常驻内存的类也需要调用BeanVO.init做一下初始化
      //所以不能在这里标记STATE_RUN_STANDBY
      thisBeanVO.state = IBeanFactory.STATE_START_LOADINFO_OK;
      if(!isReset) {
        // 放入容器中
        if(beanVOMap!=null) {
          beanVOMap.put(thisBeanVO.id, thisBeanVO);
        }
        if(loadBeanPKList!=null) {
          loadBeanPKList.add(thisBeanVO.id);
        }
      }
    }
  }

  /**
   * 设置其中一个bean的配置信息
   * 刘虻
   * 2010-2-9 下午01:40:04
   * @param beanXml    类配置信息对象
   * @param beanVOMap  类信息容器
   * @param beanVO     待重新初始化的信息容器，如果为空则为新增
   * @return           类信息对象
   * @throws Exception 执行发生异常
   */
  protected BeanVO setOneBeanFormConfig(
        IViewHandler       beanXml,
        Map<String,BeanVO> beanVOMap,
        BeanVO             beanVO) throws Exception {
    // 循环设置类
    if (beanXml == null) {
      return beanVO;
    }
    // 获取类主键
    String id = SString.valueOf(beanXml.getAttribute(IBeanFactory.TAG_BEAN_ID));
    // 无主键bean  比如动作类，不需要其它类调用
    if (id.length()<1) {
      id = getNewBeanID();
    }
    // 屏蔽此类
    if (SBoolean.valueOf(
      confProp.getFixParameter(
        beanXml.getAttribute(IBeanFactory.TAG_BEAN_DISABLED)))) {
      /*
        从来没认真看过哪些被屏蔽的类，这些日志目前来看没多大价值
        随后框架会预制一些被禁止的类，可以通过在参数配置文件中声明开放
       log
        .warning(
          "The Bean ["
            + id
            + "] is Disabled. Please Check attribute:[disabled] in the config file. config file path:["
            + beanXml.getLocationInfo() + "]", null);
      */
      return beanVO;
    }

    // 判断是否主键冲突
    // 2007-02-01 不用判断beanId是否重复，开始加载配置文件时，
    // 先加载指定配置文件中引用的配置文件，然后再加载当前指定配置文件
    // 如果当前指定配置文件中包含引用配置文件中的bean，则覆盖之
    // if (getBeanVOMap().containsKey(pk)) {
    // throw new BeanException(
    // "bean pk in the tag not single,pk="
    // +pk+" master config path="+getFilePath());
    // }
    
    //相同类信息序列
    StringBuffer infoSbf = null;
    if (beanVOMap!=null && beanVOMap.containsKey(id)) {
      infoSbf = new StringBuffer();
      infoSbf
        .append("\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n")
        .append("The Bean:[")
        .append(id)
        .append("] PK Is Repeat\n");
      
      //获取原始类信息容器
      BeanVO sBeanVO = beanVOMap.get(id);
      if (sBeanVO!=null) {
        infoSbf
          .append("ID:[")
          .append(id)
          .append("] ClassPath:[")
          .append(BeanVOUtil.getClassPath(beanFactory,sBeanVO))
          .append("] ConfigPath:[")
          .append(sBeanVO.sourceInfo)
          .append("]\n");
      }
    }
    //是否为抽象父类(抽象父类不用构造类路径)
    String isParent = beanXml.getAttribute(IBeanFactory.TAG_BEAN_ISPARENT);
    // 设置bean的类路径
    String classPath = 
      SString.valueOf(
          beanXml.getAttribute(IBeanFactory.TAG_BEAN_CLASS));
    if (classPath.length()<1 && !SBoolean.valueOf(isParent)) {
      //配置文件中没有设置类路径 尝试通过用配置文件路径获取同文件夹中同名的类路径
      classPath = beanXml.getLocationInfo();
      if(classPath.length()<1) {
        throw new BeanException("Bean class in the tag not set,ID:["
          + id + "] master config path="+beanXml.getLocationInfo());
      }
      classPath = classPath.substring(0,classPath.lastIndexOf("."))+".class";
      // 将类文件路径转换成类路径
      try {
        classPath = ClassUtil.getClassPathByFilePath(classPath);
      }catch(Exception e) {
        e.printStackTrace();
      }
      if (classPath==null || classPath.length()==0) {
        throw new BeanException("Bean class in the tag not set,ID:["
          + id + "] master config path="+beanXml.getLocationInfo());
      }
    }
    if(beanVO==null) {
      beanVO = new BeanVO();
      beanVO.id = id;  //类主键
    }
    beanVO.classPath = classPath; //设置类路径
    //从类内部设置类的基本信息，然后再用xml配置文件中的覆盖基本信息
    BeanVOUtil.loadClassInfo(beanFactory,beanVO);
    beanVO.state = IBeanFactory.STATE_START_LOADINFO_E; //设置启动中
    /*
     * 下面设置的属性值如果不存在，则需要设置为空，或者干脆不要设置
     * 因为在BeanVO中需要判断如果为空，尝试获取父类配置信息
     */
    //父类主键
    String info = beanXml.getAttribute(IBeanFactory.TAG_BEAN_PARENT_ID);
    if(info.length()>0) {
      beanVO.parentID =info;
    }
    //调用注册类主键
    info = beanXml.getAttribute(IBeanFactory.TAG_BEAN_REGISTER_ID);
    if(info.length()>0) {
      beanVO.beanRegister = info;
    }
    //设置类加载器启动后调用的方法
    info = beanXml.getAttribute(IBeanFactory.TAG_AFTER_START_METHOD);
    if(info.length()>0) {
      beanVO.afterStartMethodName = info;
    }
    //设置初始化方法名
    info = beanXml.getAttribute(IBeanFactory.TAG_BEAN_INIT_METHOD);
    if(info.length()>0) {
      beanVO.initMethodName = info;
    }
    //设置终止方法名
    info = beanXml.getAttribute(IBeanFactory.TAG_BEAN_DESTROY_METHOD);
    if(info.length()>0) {
      beanVO.destoryMethodName = info; 
    }
    //设置驻留内存优先等级 0不驻留内存  1~无穷大  优先等级由低到高
    info = confProp.getFixParameter(beanXml.getAttribute(IBeanFactory.TAG_BEAN_SINGLETON));
    if(info.length()>0) {
      beanVO.singletonLevel = SInteger.valueOf(info);
    }
    if(isParent.length()>0) {
      beanVO.isParent = SBoolean.valueOf(isParent); //设置是否为抽象父类
    }
    beanVO.state = IBeanFactory.STATE_REST_LIVE; //设置没有初始化
    if(beanVO.classPath!=null && beanVO.classPath.length()>0) {
      BeanVOUtil.getBeanClass(beanFactory,beanVO); //设置对应的类
    }
    beanVO.sourceInfo = beanXml.getLocationInfo();
    // 设置bean属性信息
    setPropTag(beanVO, beanXml);
    if (infoSbf!=null) {
      infoSbf
        .append("ID:[")
        .append(id)
        .append("] ClassPath:[")
        .append(BeanVOUtil.getClassPath(beanFactory,beanVO))
        .append("] ConfigPath:[")
        .append(beanVO.sourceInfo)
        .append("]\n")
        .append("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
      log.startLog(infoSbf);
    }
    // 输出日志
    log.startLog(
        "Load Bean ID:["
          + id
          +"] ClassPath:["
          + beanVO.classPath
          + "] VER:["
          + beanVO.beanVer
          + "] ["
          + beanVO.classTitle
          + "]");
    return beanVO;
  }

  /**
   * 将配置文件中，bean的参数信息设置到BeanVO中
   * @author 刘虻 
   * 2006-10-11下午04:07:21
   * @param beanVO         指定的BeanVO
   * @param xml            对应的配置信息对象
   * @throws BeanException 设置配置信息时发生异常
   */
  protected void setPropTag(BeanVO beanVO, IViewHandler xml) throws BeanException {
    // 获取bean的参数段
    List<IViewHandler> xmls = xml.getChildNodesByNodeName("property");
    for (IViewHandler cXml:xmls) {
      setOnePropTag(beanVO,cXml);
    }
  }

  /**
   * 设置一个参数
   * @author 刘虻 
   * 2006-10-11下午04:35:27
   * @param beanVO         指定BeanVO
   * @param xml            配置信息类
   * @throws BeanException 执行发生异常
   */
  protected void setOnePropTag(BeanVO beanVO, IViewHandler xml) throws BeanException {
    // 获取参数名
    String  propName = SString.valueOf(xml.getAttribute(IBeanFactory.TAG_BEAN_PROPERTY_NAME));
    
    //日志量太多，不需要展示该日志
    //log.startLog("Begin Set One Prop Tag BeanID:["+beanVO.id+"] propName:["+propName+"]");
    
    Boolean isVar    = null; //是否为变量名
    if(propName.length()<1) {
      /*
       * 如果不存在参数方法名信息，则检查是否存在变量名信息
       */
      propName = SString.valueOf(xml.getAttribute(IBeanFactory.TAG_BEAN_PROPERTY_VAR));
      if(propName.length()<1) {
        throw new BeanException("This property not set name:\n"+xml.nt());
      }
      isVar = new Boolean(true);
    }else {
      isVar = new Boolean(false);
    }
    // 获取参数值
    Object[] propObjs = getPropObject(xml, false);
    if (propObjs != null) {
      if (propObjs[0] == null) {
        log.error("Prop type is null:type name:[" + propName
          + "] xmlFile:[" + xml.getLocationInfo()
          + "] xml:\n" + xml.nt(), null);
      }
      beanVO.propNames.add(propName); // 添加参数名
      beanVO.propClasses.add(propObjs[0]); // 添加参数类型
      beanVO.propObjects.add(propObjs[1]); // 添加参数实例
      beanVO.propIsVars.add(isVar);
    }
  }

  /**
   * 获取配置文件中指定参数信息
   * @author 刘虻 
   * 2007-3-13下午02:30:14
   * @param xml            配置文件对象
   * @param isArray        是否为数组元素 通常用在数组元素为1
   * @return               [0]参数类型 [1]参数值实例
   * @throws BeanException 执行发生异常
   */
  protected Object[] getPropObject(IViewHandler xml, boolean isArray) throws BeanException {
    // 构造返回值
    Object[] reObjs = new Object[2];
    if(xml==null) {
      return reObjs;
    }
    // 获得参数信息
    List<IViewHandler> cxmls = xml.getChildDealNodes();
    if (cxmls.size()<1) {
      // 如果当前节点没有子节点，则被认为是末级字符串
      reObjs[0] = String.class;
      reObjs[1] = confProp.getFixParameter(xml.nt());
      return reObjs;
    }
    String[] typeNames = new String[cxmls.size()]; // 参数类型名称数组
    Object[] propClasses = new Object[cxmls.size()]; // 参数类型数组
    Object[] propValues = new Object[cxmls.size()]; // 参数元素值数组
    IViewHandler cXml; //元素
    String tValue; //参数值
    for (int i = 0; i < cxmls.size(); i++) {
      cXml = cxmls.get(i);
      // 获取参数类型名
      typeNames[i] = cXml.nn();
      if (typeNames[i].length()<1) {
        // 无效参数类型
        throw new BeanException("Xml prop element type name is null:"+ xml.nt());
      }
      // 根据不同的类型设置不同的类型值
      if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_String)) {
        propClasses[i] = String.class;
        //参数值
        propValues[i] = confProp.getFixParameter(cXml.nt());
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_int)) {
        propClasses[i] = int.class;
        //参数值
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Integer(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not int type:\n"+ xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Integer)) {
        propClasses[i] = Integer.class;
        //参数值
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Integer(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not Integer type:\n"+ xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_long)) {
        propClasses[i] = long.class;
        //参数值
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Long(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not long type:\n"+ xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Long)) {
        propClasses[i] = Long.class;
        //参数值
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Long(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not Long type:\n"+ xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_boolean)) {
        propClasses[i] = boolean.class;
        tValue = 
          confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "false";
        }
        try {
          propValues[i] = new Boolean(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not boolean type:\n"+ xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Boolean)) {
        propClasses[i] = Boolean.class;
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "false";
        }
        try {
          propValues[i] = new Boolean(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not boolean type:\n"+ xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_HashMap)) {
        propClasses[i] = HashMap.class;
        Object key = null; // 临时主键
        Object value = null; // 临时值
        // 构建参数值
        HashMap<Object,Object> valueHasm = new HashMap<Object,Object>();
        // 获取容器元素
        List<IViewHandler> elementXmls = 
            cXml.getChildNodesByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_MAP_VALUE);
        for (IViewHandler elementXml:elementXmls) {
          if (elementXml.a(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY).length()>0) {
            // 判断格式是否为 <value key="key1">value1</value>
            // value1 可以是一个非字符串的对象
            key = elementXml.a(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY);
            value = getPropObject(elementXml,false)[1];
          } else {
            // 判断格式是否为<value><key>key1</key><value>value1</value></value>
            // key1 可以是一个非字符串的对象
            key = getPropObject(
              elementXml.getFirstChildNodeByNodeName(
                IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY),
                false)[1];
            value = getPropObject(
              elementXml.getFirstChildNodeByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_MAP_VALUE),
              false)[1];
          }
          valueHasm.put(key, value);
        }
        propValues[i] = valueHasm;
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Map)) {
        propClasses[i] = Map.class;
        Object key     = null; // 临时主键
        Object value   = null; // 临时值
        // 构建参数值
        HashMap<Object,Object> valueHasm = new HashMap<Object,Object>();
        // 获取容器元素
        List<IViewHandler> elementXmls = cXml.getChildNodesByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_MAP_VALUE);
        for (IViewHandler element:elementXmls) {
          if (element.a(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY).length()>0) {
            // 判断格式是否为 <value key="key1">value1</value>
            key   = element.a(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY);
            value = getPropObject(element,false)[1];
          } else {
            // 判断格式是否为<value><key>key1</key><value>value1</value></value>
            key   = getPropObject(element.getFirstChildNodeByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY),false)[1];
            value = getPropObject(element.getFirstChildNodeByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_MAP_VALUE),false)[1];
          }
          valueHasm.put(key, value);
        }
        propValues[i] = valueHasm;
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_ArrayList)) {
        propClasses[i] = ArrayList.class;
        // 构建参数实例
        ArrayList<Object> valueArrl = new ArrayList<Object>();
        // 获取容器元素
        List<IViewHandler> elementXmls = cXml.getChildNodesByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_LIST_ELEMENT);
        List<IViewHandler> childElements; //获取元素信息数组
        for (IViewHandler elementXml:elementXmls) {
          childElements = elementXml.getChildDealNodes();
          if (childElements.size()<1) {
            // 判断参数值是否为 <value>string1</value>
            valueArrl.add(confProp.getFixParameter(elementXml.nt()));
          } else {
            // 判断参数值是否为 <value><String>string1</String></value> 或者为非字符串对象
            valueArrl.add(getPropObject(elementXml, false)[1]);
          }
        }
        propValues[i] = valueArrl;
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_List)) {
        propClasses[i] = List.class;
        // 构建参数实例
        ArrayList<Object> valueArrl = new ArrayList<Object>();
        // 获取容器元素
        List<IViewHandler> elementXmls = 
            cXml.getChildNodesByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_LIST_ELEMENT);
        List<IViewHandler> childElements; //获取元素信息数组
        for (IViewHandler elementXml:elementXmls) {
          //获取元素信息数组
          childElements = elementXml.getChildDealNodes();
          if (childElements.size()<1) {
            // 判断参数值是否为 <value>string1</value>
            valueArrl.add(confProp.getFixParameter(elementXml.nt()));
          } else {
            // 判断参数值是否为 <value><String>string1</String></value>
            valueArrl.add(getPropObject(elementXml,false)[1]);
          }
        }
        propValues[i] = valueArrl;
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_ref)) {
        propClasses[i] = ILangType.TYPE_ref;
        //获取是否为本地调用
        tValue = cXml.a(IBeanFactory.TAG_BEAN_PROPERTY_REF);
        if (tValue.length()<1) {
          throw new BeanException("The ref property not set attrib:\n"+ xml.nt());
        }
        propValues[i] = tValue;
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_byte)) {
        propClasses[i] = byte.class;
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Byte(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not byte type:\n"+xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Byte)) {
        propClasses[i] = Byte.class;
        //参数值
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Byte(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not Long Byte:\n"+xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_float)) {
        propClasses[i] = float.class;
        //参数值
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Float(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not float type:\n"+xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Float)) {
        propClasses[i] = Float.class;
        //参数值
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Float(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not Long Float:\n"+xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_double)) {
        propClasses[i] = double.class;
        //参数值
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Double(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not double type:\n"+xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Double)) {
        propClasses[i] = Double.class;
        //参数值
        tValue = confProp.getFixParameter(cXml.nt());
        if (tValue.length()<1) {
          tValue = "0";
        }
        try {
          propValues[i] = new Double(tValue);
        } catch (Exception e) {
          throw new BeanException("The property not Long Double:\n"+ xml.nt());
        }
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Hashtable)) {
        propClasses[i] = Hashtable.class;
        Object key = null; // 临时主键
        Object value = null; // 临时值
        // 构建参数值
        Hashtable<Object,Object> valueHast = new Hashtable<Object,Object>();
        // 获取容器元素
        List<IViewHandler> elementXmls = 
            cXml.getChildNodesByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_MAP_VALUE);
        for (IViewHandler elementXml:elementXmls) {
          if (elementXml.a(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY).length()>0) {
            // 判断格式是否为 <value key="key1">value1</value>
            key = elementXml.a(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY);
            value = getPropObject(elementXml, false)[1];
          } else {
            // 判断格式是否为<value><key>key1</key><value>value1</value></value>
            key = getPropObject(
              elementXml.getFirstChildNodeByNodeName(
                IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY),false)[1];
            value = getPropObject(
              elementXml
                .getFirstChildNodeByNodeName(
                  IBeanFactory.TAG_BEAN_PROPERTY_MAP_VALUE),false)[1];
          }
          if (key != null && value != null) {
            valueHast.put(key, value);
          }
        }
        propValues[i] = valueHast;
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Vector)) {
        propClasses[i] = Vector.class;
        // 构建参数实例
        Vector<Object> valueVec = new Vector<Object>();
        // 获取容器元素
        List<IViewHandler> elementXmls = 
          cXml.getChildNodesByNodeName(
            IBeanFactory.TAG_BEAN_PROPERTY_LIST_ELEMENT);
        List<IViewHandler> childElements;
        for (IViewHandler elementXml:elementXmls) {
          childElements = elementXml.getChildDealNodes();
          if (childElements.size()<1) {
            // 判断参数值是否为 <value>string1</value>
            valueVec.add(confProp.getFixParameter(elementXml.nt()));
          } else {
            // 判断参数值是否为 <value><String>string1</String></value>
            valueVec.add(getPropObject(elementXml, false)[1]);
          }
        }
        propValues[i] = valueVec;
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_Properties)) {
        propClasses[i] = Properties.class;
        Object key   = null; // 临时主键 只能是字符串型
        Object value = null; // 临时值
        // 构建参数值
        Properties valueProp = new Properties();
        // 获取容器元素
        List<IViewHandler> elementXmls = 
          cXml.getChildNodesByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_MAP_VALUE);
        for (IViewHandler elementXml:elementXmls) {
          if (elementXml.a(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY).length()>0) {
            // 判断格式是否为 <value key="key1">value1</value>
            key   = elementXml.a(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY);
            value = confProp.getFixParameter((elementXml.nt()));
          } else {
            // 判断格式是否为<value><key>key1</key><value>value1</value></value>
            key   = getPropObject(elementXml.getFirstChildNodeByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_MAP_KEY),false)[1];
            value = getPropObject(elementXml.getFirstChildNodeByNodeName(IBeanFactory.TAG_BEAN_PROPERTY_MAP_VALUE),false)[1];
          }
          if (key != null && value != null) {
            valueProp.put(key, value);
          }
        }
        propValues[i] = valueProp;
      } else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_XML)) {
        propClasses[i] = IViewHandler.class;
        try {
          propValues[i] = cXml.clone();
        }catch(Exception e) {
          e.printStackTrace();
        }
      } else if (typeNames[i].equals(ILangType.TYPE_Array)) {
        // 获取返回值
        Object[] elementObjs = getPropObject(cXml, true);
        if (elementObjs != null) {
          propClasses[i] = elementObjs[0];
          propValues[i] = elementObjs[1];
        }
      }else if (typeNames[i].equalsIgnoreCase(ILangType.TYPE_PATH)) {
        //路径 配置文件中设置的是相对路径，设置到类实例中会转换成绝对路径
        propClasses[i] = String.class;
        propValues[i]  = confProp.getFixParameter(cXml.nt());
        if (propValues[i] == null) {
          propValues[i] = beanFactory.getWebInfPath();
        }else {
          propValues[i] = 
            SFilesUtil.getAllFilePath((String)propValues[i],beanFactory.getWebInfPath());
        }
      }
    }
    // 如果元素是1，并且不是数组
    if (propClasses.length == 1 && !isArray) {
      reObjs[0] = propClasses[0];
      reObjs[1] = propValues[0];
    } else {
      boolean isObjectArray = false; // 是否为Object数组
      if (propClasses.length > 1) {
        for (int i = 1; i < propClasses.length; i++) {
          if (propClasses[0] == null) {
            if (propClasses[i] != null) {
              break;
            } else {
              continue;
            }
          }
          if (!propClasses[0].equals(propClasses[i])) {
            isObjectArray = true;
            break;
          }
        }
      }
      if (isObjectArray) {
        reObjs[0] = Object[].class;
        reObjs[1] = propValues;
      } else {
        if (propClasses[0] != null) {
          if (SString.valueOf(propClasses[0])
            .equalsIgnoreCase(ILangType.TYPE_ref)) {
            reObjs[0] = ILangType.TYPE_refs;
            reObjs[1] = propValues;
          } else {
            reObjs[1] = Array.newInstance((Class<?>) propClasses[0],propClasses.length);
            reObjs[0] = reObjs[1].getClass();
            for (int i = 0; i < propClasses.length; i++) {
              ((Object[]) reObjs[1])[i] = propValues[i];
            }
          }
        } else {
          throw new BeanException("The set prop is null xmlPath["
            + xml.getLocationInfo() + "] xml:[" + xml.nt()
            + "]");
        }
      }
    }
    return reObjs;
  }

  /**
   * 添加指定配置文件中的类信息
   * 刘虻
   * 2010-2-3 下午02:31:30
   * @param configFilePath 配置文件绝对路径
   * @param beanVOMap      类信息对象容器
   * @return               返回新加载的类主键序列
   * @throws Exception     执行发生异常
   */
  public ArrayList<String> addBeanVO(
    String             configFilePath,
    Map<String,BeanVO> beanVOMap) throws Exception {
    //构建返回值
    ArrayList<String> reList = new ArrayList<String>();
    parseBeanVO(configFilePath,beanVOMap,reList,null);
    return reList;
  }
  
  /**
   * 通过类文件路径，构造指定类，尝试获取类内部的（或其父类的 ) PARENT_BEAN_ID 
   * 值，通过该值获取其父配置信息，按照父配置信息配置当前类
   * 刘虻
   * 2012-12-11 下午3:34:58
   * @param classFilePath 类文件路径
   * @param beanVOMap     类信息容器
   * @param cl            专用类加载器
   * @return              构造后的类信息容器
   */
  public BeanVO addBeanVOFromClassFilePath(
    String             classFilePath,
    Map<String,BeanVO> beanVOMap,
    ClassLoader        cl) {
    try {
      //通过类文件路径获取对应的类路径
      String classPath =  ClassUtil.getClassPathByFilePath(classFilePath);
      if(classPath==null || classPath.length()<1) {
        return null;
      }
      //指定类
      Class<?> cls = null;
      try {
        if(cl!=null) {
          cls = cl.loadClass(classPath);
        }else {
          cls = beanFactory.getClassLoader().loadClass(classPath);
        }
      }catch(NoClassDefFoundError e) {
        e.printStackTrace();
      }
      if(cls==null) {
        return null;
      }
      if(cls.isInterface()) {
        //接口类不受类加载器管理
        return null;
      }
      if(!ClassUtil.implementsClass(cls,IBean.class)) {
        //该类不受类加载器控制
        return null;
      }
      //构造当前类信息容器
      BeanVO beanVO = new BeanVO();
      beanVO.beanClass = cls;
      //获取类中声明的信息 容器中每个主键都有值，不存在为空。没有对应信息的值为空字符串
      ClassUtil.getBeanInfoByClass(beanVO);
      if(beanVO.error) {
        //该类是不是父类（不单独在类加载器中进行管理的类）
        //注意，此处的父类是标记为父类的class，并非配置文件中的父类配置信息段
        return null;
      }
      if(beanVO.id.length()<1) {
        beanVO.id = getNewBeanID(); //构建新的类主键
      }
      beanVO.classPath = classPath;
      beanVO.sourceInfo = classFilePath;
      //标记加载信息完毕  
      //不用常驻内存的类也需要调用BeanVO.init做一下初始化
      //所以不能在这里标记STATE_RUN_STANDBY
      beanVO.state = IBeanFactory.STATE_START_LOADINFO_OK;
      // 放入容器中
      beanVOMap.put(beanVO.id, beanVO);
      return beanVO;
    }catch(Exception e) {
      System.err.println(
        "XmlConfigParse.addBeanVOFromClassFilePath classFilePath:["+
        classFilePath+"] beanVOMap:["+beanVOMap+"]");
      e.printStackTrace();
    }
    return null;
  }
  
  
  /**
   * 重新初始化类信息容器
   * 刘虻
   * 2010-3-31 下午05:45:31
   * @param beanVO         类信息容器
   * @throws BeanException 执行发生异常
   */
  public void resetBeanVO(BeanVO beanVO) throws Exception {
    if(beanVO==null) {
      return;
    }
    //获取配置文件路径
    String configFilePath = SString.valueOf(beanVO.sourceInfo);
    if(configFilePath.length()<1) {
//      手动设置的类实例无法进行重新初始化
//      throw new BeanException(
//        "Not Find The Bean ID:["
//        +beanVO.getID()+"] FactoryID:["
//        +beanVO.getFactoryID()+"] Source Info");
      return;
    }
    BeanVOUtil.clearVO(beanVO); //初始化一下
    parseBeanVO(configFilePath,null,null,beanVO);
  }

  /**
   * 加载框架内部的，受类加载器控制的类
   * 2016年4月26日
   * @return 加载的类主键
   * @author MBG
   * 
   * 已停用，实在没这个必要，已经做过测试
   */
  /*
  @SuppressWarnings("unchecked")
  public void loadInsideBean() {
    if(loadInsideBean) {
      return;
    }
    loadInsideBean = true;
    //框架包文件路径
    String jarPath = 
        getClass()
          .getProtectionDomain()
            .getCodeSource()
              .getLocation()
                .getFile();
    if(!jarPath.toLowerCase().endsWith(".jar")) {
      return;
    }
    //搜索到的文件路径序列（相对路径）
    List<String> fileList = new ArrayList<String>();
    //搜索文件扩展名序列
    List<String> extNameList = new ArrayList<String>();
    extNameList.add("class");
    //执行搜索
    SFilesUtil.searchZipFilePath(fileList,jarPath,null,extNameList,true);
    
    //构建返回值
    List<String> beanIdList = new ArrayList<>();
    
    Class<?> cls; //搜索到的类
    String[] infos; //类信息
    for(String ele:fileList) {
      try {
        //将文件路径转换为类路径
        ele = ele.substring(0,ele.length()-6);
        ele = ele.replace('/','.');
        
        //构造类
        cls = Class.forName(ele);
        if(cls.isInterface()) {
          continue;
        }
        infos = ClassUtil.getBeanInfo(cls);
        if(infos[0].length()>0 && SBoolean.valueOf(infos[4])) {
          //放入类加载器
          beanIdList.add(beanFactory.setClass((Class<IBean>)cls,false));
        }
      }catch(Exception e) {
        e.printStackTrace();
      }
    }
    //执行初始化
    try {
      beanFactory.initBeanVOList(beanIdList);
      
      beanFactory.commitInitBean(beanIdList);
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
  */
}
